struct Circle {
    x: f64,
    y: f64,
    radius: f64,
}

struct CircleBuilder {
    x: f64,
    y: f64,
    radius: f64,
}

impl Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * (self.radius * self.radius)
    }

    fn new() -> CircleBuilder {
        CircleBuilder {
            x: 0.0,
            y: 0.0,
            radius: 1.0
        }
    }
}

impl CircleBuilder {
    fn x(&mut self, coordinate: f64) -> &mut CircleBuilder {
        self.x = coordinate;
        self
    }

    fn y(&mut self, coordinate: f64) -> &mut CircleBuilder {
        self.y = coordinate;
        self
    }

    fn radius(&mut self, coordinate: f64) -> &mut CircleBuilder {
        self.radius = coordinate;
        self
    }

    fn build(&self) -> Circle {
        Circle {
            x: self.x,
            y: self.y,
            radius: self.radius,
        }
    }
}

#[cfg(test)]
mod test {
    use crate::chapter7::design_mode_builder::Circle;
    use std::process::Command;

    #[test]
    fn test() {
        let c = Circle::new().x(1.0).y(2.0).radius(2.0)
            .build();

        assert_eq!(c.area(), 12.566370614359172);
        assert_eq!(c.x, 1.0);
        assert_eq!(c.y, 2.0);
    }

    // 在 rust 标准库中有一个用于创建进程的结构体 std::process:Command, 它使用了创建者模式。
    #[test]
    fn test_command() {
        Command::new("ls")
            .arg("-1")
            .arg("-a")
            .spawn()
            .expect("ls command failed to start");
    }
}